Skip to content

Conversation

@ric-yu
Copy link

@ric-yu ric-yu commented Dec 4, 2025

Summary

Add Jobs API infrastructure in preparation for migrating from legacy /history, /history_v2, and /queue endpoints to the unified /jobs API.

This is PR 1 of 3 - Additive changes only, no breaking changes.

Changes

  • What:

    • Add Zod schemas for runtime validation of Jobs API responses (JobListItem, JobDetail)
    • Add fetchQueue, fetchHistory, fetchJobDetail fetchers for /jobs endpoint
    • Add extractWorkflow utility for extracting workflow from nested job detail response
    • Add synthetic priority assignment for queue ordering (pending > running > history)
    • Add comprehensive tests for all new fetchers
  • Non-breaking: All changes are additive - existing code continues to work

Review Focus

  1. Zod schema flexibility: Using .passthrough() to allow extra API fields - ensures forward compatibility but less strict validation
  2. Priority computation: Synthetic priority ensures display order: pending (queued) → running → completed (history)
  3. Test coverage: Verify tests adequately cover edge cases

Files Added

  • src/platform/remote/comfyui/jobs/ - New Jobs API module
    • types/jobTypes.ts - Zod schemas and TypeScript types
    • fetchers/fetchJobs.ts - API fetchers with validation
    • index.ts - Barrel exports
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts - Tests

Next PRs

  • PR 2: Migrate getQueue() and getHistory() to use Jobs API
  • PR 3: Remove legacy history code and unused types

┆Issue is synchronized with this Notion page by Unito

@ric-yu ric-yu requested a review from a team as a code owner December 4, 2025 23:53
@dosubot dosubot bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Dec 4, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 4, 2025

📝 Walkthrough

Walkthrough

Adds a ComfyUI Jobs fetcher module that validates API responses, retrieves job history, queue, and individual job details, assigns synthetic priorities, extracts embedded workflows, and exposes these functions via a consolidated public API surface with accompanying types and tests.

Changes

Cohort / File(s) Change Summary
Type definitions & schemas
src/platform/remote/comfyui/jobs/types/jobTypes.ts
New Zod schemas and TypeScript types for Jobs API responses: job status enum, preview/output schemas, execution error, raw job item, job detail, pagination, and jobs list response; exports types like JobStatus, RawJobListItem, JobListItem, JobDetail, and ExecutionError.
Fetcher implementation
src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
New unified Jobs API fetcher: fetchJobsRaw for paginated requests with validation and error handling; fetchHistory, fetchQueue for listing with synthetic priority assignment (including QUEUE_PRIORITY_BASE and assignPriority helper); fetchJobDetail for single-job retrieval; extractWorkflow to pull embedded workflow JSON.
Public API export
src/platform/remote/comfyui/jobs/index.ts
New barrel module re-exporting fetchHistory, fetchQueue, fetchJobDetail, and extractWorkflow from the fetcher implementation.
Tests
tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
New test suite with mocked fetch responses validating history/queue retrieval, priority assignment and ordering, job detail fetching, workflow extraction, and error/non-OK handling.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jobs-api-pr1-infrastructure

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5cb2579 and 0a619ec.

📒 Files selected for processing (4)
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts (1 hunks)
  • src/platform/remote/comfyui/jobs/index.ts (1 hunks)
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts (1 hunks)
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{vue,ts,tsx}: Leverage VueUse functions for performance-enhancing utilities
Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.json

Files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursorrules)

Use es-toolkit for utility functions

Files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

Use TypeScript for type safety

**/*.{ts,tsx}: Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue

Files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
**/*.{ts,tsx,js,vue}

📄 CodeRabbit inference engine (.cursorrules)

Implement proper error handling in components and services

**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in .prettierrc
Organize imports by sorting and grouping by plugin, and run pnpm format before committing

Files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
**/*.{ts,tsx,js,jsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Use camelCase for variable and setting names in TypeScript/Vue files

Files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,vue}: Use const settingStore = useSettingStore() and settingStore.get('Comfy.SomeSetting') to retrieve settings in TypeScript/Vue files
Use await settingStore.set('Comfy.SomeSetting', newValue) to update settings in TypeScript/Vue files
Check server capabilities using api.serverSupportsFeature('feature_name') before using enhanced features
Use api.getServerFeature('config_name', defaultValue) to retrieve server feature configuration

Enforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates

Files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Define dynamic setting defaults using runtime context with functions in settings configuration
Use defaultsByInstallVersion property for gradual feature rollout based on version in settings configuration

Files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
tests-ui/**/*.test.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)

tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks

Files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
**/*.{test,spec}.{ts,tsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

Unit and component tests should be located in tests-ui/ or co-located with components as src/components/**/*.{test,spec}.ts; E2E tests should be in browser_tests/

Files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
🧠 Learnings (12)
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Mock external dependencies in tests

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Always prefer vitest mock functions over writing verbose manual mocks

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Use existing test utilities rather than writing custom utilities

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possible

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Follow naming conventions for browser tests

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Check tests-ui/README.md for test guidelines

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{js,ts,jsx,tsx} : When adding features, always write vitest unit tests using cursor rules in @.cursor

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:23.088Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T19:48:23.088Z
Learning: Use Vitest (with happy-dom) for unit and component tests, and Playwright for E2E tests

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
🧬 Code graph analysis (3)
tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts (1)
src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts (4)
  • fetchHistory (77-90)
  • fetchQueue (96-118)
  • fetchJobDetail (127-144)
  • extractWorkflow (150-160)
src/platform/remote/comfyui/jobs/types/jobTypes.ts (1)
src/schemas/apiSchema.ts (2)
  • resultItemType (17-17)
  • zTaskOutput (245-245)
src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts (5)
src/platform/remote/comfyui/jobs/types/jobTypes.ts (6)
  • RawJobListItem (111-111)
  • JobStatus (110-110)
  • zJobsListResponse (99-104)
  • JobListItem (113-113)
  • JobDetail (114-114)
  • zJobDetail (74-82)
src/scripts/api.ts (1)
  • fetchApi (386-418)
src/platform/remote/comfyui/jobs/index.ts (4)
  • fetchHistory (10-10)
  • fetchQueue (12-12)
  • fetchJobDetail (11-11)
  • extractWorkflow (9-9)
src/schemas/apiSchema.ts (1)
  • PromptId (16-16)
src/platform/workflow/validation/schemas/workflowSchema.ts (1)
  • ComfyWorkflowJSON (460-462)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: setup
  • GitHub Check: lint-and-format
  • GitHub Check: test
  • GitHub Check: collect
🔇 Additional comments (20)
src/platform/remote/comfyui/jobs/index.ts (1)

1-13: LGTM!

Clean barrel file with proper JSDoc module documentation and well-organized re-exports for the public API surface.

tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts (5)

10-42: LGTM!

Clean, reusable mock helpers with proper default values and type inference. Good use of the overrides parameter for flexible test data creation.


45-126: LGTM!

Comprehensive test coverage for fetchHistory: URL construction, synthetic priority assignment, server-priority preservation, and both network error and HTTP error handling.


128-183: LGTM!

Good coverage of queue fetching including job partitioning, priority ordering (Pending > Running > History), and error handling. Based on past review comments, a test for non-ok HTTP response (similar to fetchHistory) would be a nice addition for parity, but current coverage is adequate.


185-226: LGTM!

Proper test coverage for fetchJobDetail: successful fetch with output verification, 404 handling, and network error handling.


228-259: LGTM!

Solid edge-case coverage for extractWorkflow: nested extraction, missing workflow data, and undefined input handling.

src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts (7)

1-28: LGTM!

Clean module structure with proper type-only imports and a well-defined internal interface for the raw fetch result.


30-54: LGTM!

Solid internal fetcher with proper error handling, Zod validation, and safe defaults. The error-as-empty-result behavior aligns with the graceful degradation design documented in PR objectives.


56-71: LGTM!

Clean priority assignment logic with proper use of nullish coalescing to preserve server-provided priorities while synthesizing when absent.


73-90: LGTM!

Correct implementation with proper pagination support and total - offset base for consistent priority across pages.


92-118: LGTM!

Correct partitioning and priority assignment ensuring Pending > Running > History ordering. The hardcoded limit and offset are appropriate for queue fetching.


120-144: LGTM!

Proper error handling with appropriate log levels (warn for 404-like responses, error for exceptions) and clear undefined contract for failures.


146-160: LGTM!

The type casts are documented with a clear justification that downstream validation via loadGraphData -> validateComfyWorkflow will catch malformed data. This is an acceptable trade-off for cleaner code, and the casts are specific types rather than any.

src/platform/remote/comfyui/jobs/types/jobTypes.ts (7)

1-11: LGTM!

Proper module documentation and clean imports that reuse existing schema components from @/schemas/apiSchema.


13-31: LGTM!

Well-defined status enum and preview output schema. The .passthrough() on zPreviewOutput enables forward compatibility with additional fields.


33-50: LGTM!

Comprehensive error schema matching the WebSocket message structure with appropriate use of z.unknown() for dynamic input/output data.


52-68: LGTM!

Well-structured raw job schema with appropriate nullable/optional modifiers for timestamps and preview data. The optional priority field enables both server-provided and synthetic priority assignment.


70-82: LGTM!

Clean schema extension pattern using zRawJobListItem.extend(). The z.unknown() for workflow is appropriate given downstream validation in extractWorkflow.


84-104: LGTM!

Standard pagination structure with useful has_more flag for UI pagination controls. Consistent use of .passthrough() for forward compatibility.


106-114: LGTM!

Clean type derivation using z.infer<> and appropriate intersection type for JobListItem to ensure priority is always present after processing.


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Dec 4, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 12/05/2025, 12:40:52 AM UTC

📈 Summary

  • Total Tests: 495
  • Passed: 482 ✅
  • Failed: 0
  • Flaky: 3 ⚠️
  • Skipped: 10 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 473 / ❌ 0 / ⚠️ 3 / ⏭️ 10
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 6 / ❌ 0 / ⚠️ 0 / ⏭️ 0

🎉 Click on the links above to view detailed test results for each browser configuration.

@github-actions
Copy link

github-actions bot commented Dec 4, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 12/05/2025, 12:32:06 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Dec 4, 2025

Bundle Size Report

Summary

  • Raw size: 17 MB baseline 17 MB — ⚪ 0 B
  • Gzip: 3.38 MB baseline 3.38 MB — ⚪ 0 B
  • Brotli: 2.59 MB baseline 2.59 MB — ⚪ 0 B
  • Bundles: 97 current • 97 baseline

Category Glance
Vendor & Third-Party ⚪ 0 B (8.56 MB) · Other ⚪ 0 B (3.81 MB) · App Entry Points ⚪ 0 B (3.2 MB) · Graph Workspace ⚪ 0 B (974 kB) · Panels & Settings ⚪ 0 B (298 kB) · UI Components ⚪ 0 B (173 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.2 MB (baseline 3.2 MB) • ⚪ 0 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-Ci-KN8RO.js 345 B 345 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/index-CSi1adXo.js 223 kB 223 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/index-Dqv_ZOH_.js 2.97 MB 2.97 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Graph Workspace — 974 kB (baseline 974 kB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-CPctgGIL.js 974 kB 974 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Views & Navigation — 6.54 kB (baseline 6.54 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-B2S3RyFZ.js 6.54 kB 6.54 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Panels & Settings — 298 kB (baseline 298 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/AboutPanel-8WSdk0Z1.js 9.16 kB 9.16 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/CreditsPanel-tdtMHtbU.js 21.4 kB 21.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ExtensionPanel-zstOuiY7.js 10.8 kB 10.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/KeybindingPanel-CjGfBaFT.js 13.6 kB 13.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/ServerConfigPanel-CkzHihHg.js 6.56 kB 6.56 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BhbWhsRg.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BXTtSH4O.js 33.3 kB 33.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C9Pzn-NG.js 25.2 kB 25.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CCy2fA_h.js 27.3 kB 27.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CQpqEFfl.js 26.6 kB 26.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DHcnxypw.js 21.7 kB 21.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DhFTK9fY.js 25.1 kB 25.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DlT4t_ui.js 25.9 kB 25.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DRgSrIdD.js 24.2 kB 24.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-tjkeqiZq.js 21.1 kB 21.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UserPanel-DHgtcXJW.js 6.23 kB 6.23 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
UI Components — 173 kB (baseline 173 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/ComfyQueueButton-GFcxiIeL.js 8.44 kB 8.44 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/LazyImage.vue_vue_type_script_setup_true_lang-DvvBfJGk.js 43.3 kB 43.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Load3D.vue_vue_type_script_setup_true_lang-D3use3ER.js 53.9 kB 53.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-mLBoQ1rc.js 897 B 897 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-CDkUGVOA.js 1.34 kB 1.34 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetButton-CbZj9xHx.js 2.04 kB 2.04 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-DD37M5Yp.js 12.9 kB 12.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-Bb3LZ5y7.js 2.26 kB 2.26 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-CdhKNttT.js 47.6 kB 47.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Data & Services — 12.5 kB (baseline 12.5 kB) • ⚪ 0 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/audioService-B1yqA1Mo.js 2.2 kB 2.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/keybindingService-C1IEfb9_.js 7.51 kB 7.51 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/serverConfigStore-uprby_D3.js 2.83 kB 2.83 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Utilities & Hooks — 2.94 kB (baseline 2.94 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/audioUtils-CrwDOilH.js 1.41 kB 1.41 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/mathUtil-CTARWQ-l.js 1.07 kB 1.07 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeFilterUtil-CXKCRJ-m.js 460 B 460 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
Vendor & Third-Party — 8.56 MB (baseline 8.56 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-chart-BhMrpT7H.js 452 kB 452 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-Djvsb6Yg.js 3.98 MB 3.98 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-vP_q3PtU.js 1.96 MB 1.96 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-aR6ntw5X.js 1.37 MB 1.37 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-abEQAgz5.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-abso1wrr.js 160 kB 160 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BZLod3g9.js 407 kB 407 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 3.81 MB (baseline 3.81 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/AudioPreviewPlayer-Dhj1P9tl.js 13.5 kB 13.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-_s-RvhJR.js 13.6 kB 13.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BuUILW6P.js 13 kB 13 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BV4R6fLx.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BWp4HdfU.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CLwPdnT6.js 14.2 kB 14.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CWMchBmd.js 15.9 kB 15.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DazTQhtc.js 12.9 kB 12.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DmWrOe93.js 13.7 kB 13.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DwiH7Kr6.js 13.8 kB 13.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-mS3LCNPn.js 14.5 kB 14.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Load3D-jZ0TOmfb.js 424 B 424 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B1JflQcI.js 72.2 kB 72.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B2lyXe48.js 114 kB 114 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-B9XEQ-pc.js 94 kB 94 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BErKFzc-.js 73.1 kB 73.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Bf7Tze-u.js 83.4 kB 83.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BhGMcO4Q.js 84.3 kB 84.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CPZUloNQ.js 99 kB 99 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cw9RZWRY.js 89 B 89 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Dva0z-T2.js 86.5 kB 86.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-un0K9wDS.js 81.8 kB 81.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Media3DBottom-DBUol5fK.js 1.5 kB 1.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/Media3DTop-D2AT_UMY.js 1.49 kB 1.49 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioBottom-BE1-CE4j.js 1.52 kB 1.52 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-DCIZ2mdC.js 1.46 kB 1.46 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageBottom-DZ1NlKIm.js 1.57 kB 1.57 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-Du4uz2Wm.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoBottom-BqHSgwzA.js 1.52 kB 1.52 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-59yKN05c.js 2.76 kB 2.76 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-8e6QYQW0.js 283 kB 283 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-A_9dx4yn.js 304 kB 304 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BbD3HDi7.js 307 kB 307 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BOJhIPft.js 369 kB 369 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Bw_Jitw_.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-C-Pw33mW.js 317 kB 317 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-ChLyG0UJ.js 285 kB 285 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CUVPxA4l.js 342 kB 342 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Dx5Y4xrW.js 310 kB 310 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-JqO5mNmW.js 306 kB 306 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetAudioUI-C7HQMFhz.js 2.82 kB 2.82 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-Beblk1io.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetColorPicker-BlAeiw_N.js 3.41 kB 3.41 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetGalleria-CA7nKdp1.js 4.1 kB 4.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-CMMfeF2r.js 2.21 kB 2.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetInputNumber-CH18WsAw.js 595 B 595 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetInputText-B2QBLQt9.js 1.99 kB 1.99 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetLegacy-DOkfbAIG.js 364 B 364 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetMarkdown-CQos0WjR.js 3.08 kB 3.08 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-BIbGSUAt.js 1.28 kB 1.28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetRecordAudio-DmFtzdLM.js 20.4 kB 20.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetSelect-4FFdgevL.js 655 B 655 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetTextarea-CoXfUnia.js 2.93 kB 2.93 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetToggleSwitch-C8WLR8XC.js 1.58 kB 1.58 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ab777bc and de0d169.

📒 Files selected for processing (5)
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts (1 hunks)
  • src/platform/remote/comfyui/jobs/index.ts (1 hunks)
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts (1 hunks)
  • src/scripts/api.ts (3 hunks)
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{vue,ts,tsx}: Leverage VueUse functions for performance-enhancing utilities
Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.json

Files:

  • src/scripts/api.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/index.ts
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursorrules)

Use es-toolkit for utility functions

Files:

  • src/scripts/api.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/index.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

Use TypeScript for type safety

**/*.{ts,tsx}: Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue

Files:

  • src/scripts/api.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/index.ts
**/*.{ts,tsx,js,vue}

📄 CodeRabbit inference engine (.cursorrules)

Implement proper error handling in components and services

**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in .prettierrc
Organize imports by sorting and grouping by plugin, and run pnpm format before committing

Files:

  • src/scripts/api.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/index.ts
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/scripts/api.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
  • src/platform/remote/comfyui/jobs/index.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/scripts/api.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
  • src/platform/remote/comfyui/jobs/index.ts
**/*.{ts,tsx,js,jsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Use camelCase for variable and setting names in TypeScript/Vue files

Files:

  • src/scripts/api.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/index.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,vue}: Use const settingStore = useSettingStore() and settingStore.get('Comfy.SomeSetting') to retrieve settings in TypeScript/Vue files
Use await settingStore.set('Comfy.SomeSetting', newValue) to update settings in TypeScript/Vue files
Check server capabilities using api.serverSupportsFeature('feature_name') before using enhanced features
Use api.getServerFeature('config_name', defaultValue) to retrieve server feature configuration

Enforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates

Files:

  • src/scripts/api.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/index.ts
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Define dynamic setting defaults using runtime context with functions in settings configuration
Use defaultsByInstallVersion property for gradual feature rollout based on version in settings configuration

Files:

  • src/scripts/api.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/index.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/scripts/api.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
  • src/platform/remote/comfyui/jobs/index.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/scripts/api.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
  • src/platform/remote/comfyui/jobs/index.ts
tests-ui/**/*.test.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)

tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks

Files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
**/*.{test,spec}.{ts,tsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

Unit and component tests should be located in tests-ui/ or co-located with components as src/components/**/*.{test,spec}.ts; E2E tests should be in browser_tests/

Files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
🧠 Learnings (9)
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Mock external dependencies in tests

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Always prefer vitest mock functions over writing verbose manual mocks

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Use existing test utilities rather than writing custom utilities

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possible

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:23.088Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T19:48:23.088Z
Learning: Use Vitest (with happy-dom) for unit and component tests, and Playwright for E2E tests

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
🧬 Code graph analysis (2)
src/platform/remote/comfyui/jobs/types/jobTypes.ts (1)
src/schemas/apiSchema.ts (2)
  • resultItemType (17-17)
  • zTaskOutput (245-245)
tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts (1)
src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts (4)
  • fetchHistory (77-90)
  • fetchQueue (96-118)
  • fetchJobDetail (127-144)
  • extractWorkflow (150-160)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: lint-and-format
  • GitHub Check: setup
  • GitHub Check: collect
  • GitHub Check: test
🔇 Additional comments (19)
src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts (6)

1-19: LGTM!

Clean module structure with clear documentation and proper imports. The file is well-organized with section separators.


34-54: LGTM!

Good defensive implementation with proper error handling. The function correctly returns safe defaults on both network errors and non-OK responses, and uses Zod for runtime validation.


63-71: LGTM!

The nullish coalescing operator correctly preserves server-provided priority while assigning synthetic priorities when not present.


77-90: LGTM!

Clean implementation with appropriate priority assignment for history items.


96-118: LGTM!

The priority computation correctly ensures the ordering: pending > running > history. The separation of jobs by status is clean and efficient.


127-144: LGTM!

Good error handling with appropriate log levels - warn for not-found cases and error for exceptions.

src/platform/remote/comfyui/jobs/index.ts (1)

1-14: LGTM!

Clean barrel file with proper separation of value and type exports. Good public API surface for the module.

tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts (5)

1-26: LGTM!

Clean helper functions for creating mock data. The helpers are reusable and make tests readable. Based on learnings, vitest mock functions are correctly used.


45-126: LGTM!

Comprehensive test coverage for fetchHistory including priority assignment, server-provided priority preservation, and error handling scenarios.


128-183: LGTM!

Good test coverage including verification that pending jobs have higher priority than running jobs.


185-226: LGTM!

Proper test coverage for fetchJobDetail including the undefined return cases.


228-259: LGTM!

Good coverage of the extractWorkflow function including edge cases for missing workflow data.

src/scripts/api.ts (3)

50-55: LGTM!

Clean import structure with clear aliasing to distinguish legacy from new Jobs API functions.


933-947: LGTM!

Clean refactoring to use the renamed legacy fetcher while maintaining backward compatibility.


1292-1333: LGTM!

Well-implemented new methods that follow the existing patterns in the class. Error handling is consistent with other methods like getQueue() and getHistory().

src/platform/remote/comfyui/jobs/types/jobTypes.ts (4)

1-11: LGTM!

Clear module documentation and proper imports. Good use of existing schemas from apiSchema.ts.


17-31: LGTM!

Good use of .passthrough() for forward compatibility with future API changes.


37-52: LGTM!

Well-structured error schema with appropriate optionality for fields that may not always be present.


54-116: LGTM!

Excellent schema design with proper composition and type derivation. The JobListItem type correctly extends RawJobListItem with a required priority field for the synthetic priority system.

Comment on lines +150 to +160
export function extractWorkflow(
job: JobDetail | undefined
): ComfyWorkflowJSON | undefined {
// Cast is safe - workflow will be validated by loadGraphData -> validateComfyWorkflow
const workflowData = job?.workflow as
| { extra_data?: { extra_pnginfo?: { workflow?: unknown } } }
| undefined
return workflowData?.extra_data?.extra_pnginfo?.workflow as
| ComfyWorkflowJSON
| undefined
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider type guards or Zod for safer workflow extraction.

The type casts bypass TypeScript's type checking. While the comment explains downstream validation will catch issues, a runtime type check here would provide earlier error detection and better type safety.

Consider using a type guard or Zod schema:

+import { zComfyWorkflow } from '@/platform/workflow/validation/schemas/workflowSchema'
+
 export function extractWorkflow(
   job: JobDetail | undefined
 ): ComfyWorkflowJSON | undefined {
-  // Cast is safe - workflow will be validated by loadGraphData -> validateComfyWorkflow
-  const workflowData = job?.workflow as
-    | { extra_data?: { extra_pnginfo?: { workflow?: unknown } } }
-    | undefined
-  return workflowData?.extra_data?.extra_pnginfo?.workflow as
-    | ComfyWorkflowJSON
-    | undefined
+  const workflowData = job?.workflow
+  if (
+    typeof workflowData === 'object' &&
+    workflowData !== null &&
+    'extra_data' in workflowData
+  ) {
+    const extraData = (workflowData as Record<string, unknown>).extra_data
+    if (typeof extraData === 'object' && extraData !== null && 'extra_pnginfo' in extraData) {
+      const pnginfo = (extraData as Record<string, unknown>).extra_pnginfo
+      if (typeof pnginfo === 'object' && pnginfo !== null && 'workflow' in pnginfo) {
+        return (pnginfo as Record<string, unknown>).workflow as ComfyWorkflowJSON | undefined
+      }
+    }
+  }
+  return undefined
 }

Committable suggestion skipped: line range outside the PR's diff.

@ric-yu ric-yu force-pushed the jobs-api-pr1-infrastructure branch from de0d169 to 5cb2579 Compare December 5, 2025 00:07
Adds Jobs API types, fetchers, and new API methods without breaking existing code.
This is the foundation for migrating from legacy /history and /queue endpoints
to the unified /jobs endpoint.

New files:
- src/platform/remote/comfyui/jobs/types/jobTypes.ts - Zod schemas for Jobs API
- src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts - Fetchers for /jobs endpoint
- src/platform/remote/comfyui/jobs/index.ts - Barrel exports
- tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts

API additions (non-breaking):
- api.getQueueFromJobsApi() - Queue from /jobs endpoint
- api.getHistoryFromJobsApi() - History from /jobs endpoint
- api.getJobDetail() - Full job details including workflow and outputs

Part of Jobs API migration. See docs/JOBS_API_MIGRATION_PLAN.md for details.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between de0d169 and 5cb2579.

📒 Files selected for processing (4)
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts (1 hunks)
  • src/platform/remote/comfyui/jobs/index.ts (1 hunks)
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts (1 hunks)
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{vue,ts,tsx}: Leverage VueUse functions for performance-enhancing utilities
Use vue-i18n in Composition API for any string literals and place new translation entries in src/locales/en/main.json

Files:

  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursorrules)

Use es-toolkit for utility functions

Files:

  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

Use TypeScript for type safety

**/*.{ts,tsx}: Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue

Files:

  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
**/*.{ts,tsx,js,vue}

📄 CodeRabbit inference engine (.cursorrules)

Implement proper error handling in components and services

**/*.{ts,tsx,js,vue}: Use 2-space indentation, single quotes, no semicolons, and maintain 80-character line width as configured in .prettierrc
Organize imports by sorting and grouping by plugin, and run pnpm format before committing

Files:

  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

Files:

  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
**/*.{ts,tsx,js,jsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

Use camelCase for variable and setting names in TypeScript/Vue files

Files:

  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,vue}: Use const settingStore = useSettingStore() and settingStore.get('Comfy.SomeSetting') to retrieve settings in TypeScript/Vue files
Use await settingStore.set('Comfy.SomeSetting', newValue) to update settings in TypeScript/Vue files
Check server capabilities using api.serverSupportsFeature('feature_name') before using enhanced features
Use api.getServerFeature('config_name', defaultValue) to retrieve server feature configuration

Enforce ESLint rules for Vue + TypeScript including: no floating promises, no unused imports, and i18n raw text restrictions in templates

Files:

  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Define dynamic setting defaults using runtime context with functions in settings configuration
Use defaultsByInstallVersion property for gradual feature rollout based on version in settings configuration

Files:

  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/platform/remote/comfyui/jobs/index.ts
  • src/platform/remote/comfyui/jobs/types/jobTypes.ts
  • src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts
tests-ui/**/*.test.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)

tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks

Files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
**/*.{test,spec}.{ts,tsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

Unit and component tests should be located in tests-ui/ or co-located with components as src/components/**/*.{test,spec}.ts; E2E tests should be in browser_tests/

Files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
🧠 Learnings (9)
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Mock external dependencies in tests

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Always prefer vitest mock functions over writing verbose manual mocks

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Use existing test utilities rather than writing custom utilities

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Mocks should be cleanly written and easy to understand, with reusable mocks where possible

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:23.088Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T19:48:23.088Z
Learning: Use Vitest (with happy-dom) for unit and component tests, and Playwright for E2E tests

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts
🧬 Code graph analysis (2)
src/platform/remote/comfyui/jobs/types/jobTypes.ts (1)
src/schemas/apiSchema.ts (2)
  • resultItemType (17-17)
  • zTaskOutput (245-245)
tests-ui/tests/platform/remote/comfyui/jobs/fetchers/fetchJobs.test.ts (1)
src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts (4)
  • fetchHistory (77-90)
  • fetchQueue (96-118)
  • fetchJobDetail (127-144)
  • extractWorkflow (150-160)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: deploy-and-comment
  • GitHub Check: test
  • GitHub Check: setup
  • GitHub Check: collect
  • GitHub Check: lint-and-format
🔇 Additional comments (2)
src/platform/remote/comfyui/jobs/index.ts (1)

1-14: Jobs API barrel exports look correct and cohesive

Centralizing extractWorkflow, fetchHistory, fetchJobDetail, fetchQueue, and the key types behind this index gives a clean, future‑proof surface for callers; no issues from my side.

src/platform/remote/comfyui/jobs/types/jobTypes.ts (1)

1-116: Jobs API schemas and derived types look consistent and forward‑compatible

The schema set (status, preview, execution error, raw item, detail, pagination, list response) together with .passthrough() where appropriate gives you robust validation while still tolerating backend evolution. The split between RawJobListItem (as returned) and JobListItem (with guaranteed priority) is a clean contract for the fetchers and UI; I don’t see any issues here.

Comment on lines +24 to +160
interface FetchJobsRawResult {
jobs: RawJobListItem[]
total: number
offset: number
}

/**
* Fetches raw jobs from /jobs endpoint
* @internal
*/
async function fetchJobsRaw(
fetchApi: (url: string) => Promise<Response>,
statuses: JobStatus[],
maxItems: number = 200,
offset: number = 0
): Promise<FetchJobsRawResult> {
const statusParam = statuses.join(',')
const url = `/jobs?status=${statusParam}&limit=${maxItems}&offset=${offset}`
try {
const res = await fetchApi(url)
if (!res.ok) {
console.error(`[Jobs API] Failed to fetch jobs: ${res.status}`)
return { jobs: [], total: 0, offset: 0 }
}
const data = zJobsListResponse.parse(await res.json())
return { jobs: data.jobs, total: data.pagination.total, offset }
} catch (error) {
console.error('[Jobs API] Error fetching jobs:', error)
return { jobs: [], total: 0, offset: 0 }
}
}

// Large offset to ensure running/pending jobs sort above history
const QUEUE_PRIORITY_BASE = 1_000_000

/**
* Assigns synthetic priority to jobs.
* Only assigns if job doesn't already have a server-provided priority.
*/
function assignPriority(
jobs: RawJobListItem[],
basePriority: number
): JobListItem[] {
return jobs.map((job, index) => ({
...job,
priority: job.priority ?? basePriority - index
}))
}

/**
* Fetches history (completed jobs)
* Assigns synthetic priority starting from total (lower than queue jobs).
*/
export async function fetchHistory(
fetchApi: (url: string) => Promise<Response>,
maxItems: number = 200,
offset: number = 0
): Promise<JobListItem[]> {
const { jobs, total } = await fetchJobsRaw(
fetchApi,
['completed'],
maxItems,
offset
)
// History gets priority based on total count (lower than queue)
return assignPriority(jobs, total - offset)
}

/**
* Fetches queue (in_progress + pending jobs)
* Pending jobs get highest priority, then running jobs.
*/
export async function fetchQueue(
fetchApi: (url: string) => Promise<Response>
): Promise<{ Running: JobListItem[]; Pending: JobListItem[] }> {
const { jobs } = await fetchJobsRaw(
fetchApi,
['in_progress', 'pending'],
200,
0
)

const running = jobs.filter((j) => j.status === 'in_progress')
const pending = jobs.filter((j) => j.status === 'pending')

// Pending gets highest priority, then running
// Both are above any history job due to QUEUE_PRIORITY_BASE
return {
Running: assignPriority(running, QUEUE_PRIORITY_BASE + running.length),
Pending: assignPriority(
pending,
QUEUE_PRIORITY_BASE + running.length + pending.length
)
}
}

// ============================================================================
// Job Detail Fetcher
// ============================================================================

/**
* Fetches full job details from /jobs/{job_id}
*/
export async function fetchJobDetail(
fetchApi: (url: string) => Promise<Response>,
promptId: PromptId
): Promise<JobDetail | undefined> {
try {
const res = await fetchApi(`/jobs/${promptId}`)

if (!res.ok) {
console.warn(`Job not found for prompt ${promptId}`)
return undefined
}

return zJobDetail.parse(await res.json())
} catch (error) {
console.error(`Failed to fetch job detail for prompt ${promptId}:`, error)
return undefined
}
}

/**
* Extracts workflow from job detail response.
* The workflow is nested at: workflow.extra_data.extra_pnginfo.workflow
*/
export function extractWorkflow(
job: JobDetail | undefined
): ComfyWorkflowJSON | undefined {
// Cast is safe - workflow will be validated by loadGraphData -> validateComfyWorkflow
const workflowData = job?.workflow as
| { extra_data?: { extra_pnginfo?: { workflow?: unknown } } }
| undefined
return workflowData?.extra_data?.extra_pnginfo?.workflow as
| ComfyWorkflowJSON
| undefined
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Fetchers, priority logic, and error handling look solid with a couple of trade‑offs to be aware of

Overall the implementation matches the design goals well:

  • fetchJobsRaw centralizes URL building and response validation, and safely degrades to empty results on any HTTP/parse error.
  • assignPriority’s “only synthesize when priority is nullish” behavior cleanly preserves server ordering while still giving you a total/offset‑based fallback.
  • fetchHistory and fetchQueue cooperate to ensure the intended ordering (Pending > Running > History), and the total - offset base in history should keep priorities consistent across pages.
  • fetchJobDetail and extractWorkflow give callers a simple undefined contract on failure while logging enough context for debugging.

Two non‑blocking considerations:

  • QUEUE_PRIORITY_BASE = 1_000_000 assumes the maximum history priority will remain below that; if very large installations could exceed this, you might eventually want to derive the base from an upper bound (e.g., a config or Number.MAX_SAFE_INTEGER margin).
  • All failures in fetchJobsRaw surface to callers as “no jobs” rather than a hard error; if future UX needs to distinguish “empty history/queue” from “failed to load”, you may want a variant that returns an error flag alongside the jobs.

Nothing here looks blocking; the current behavior is coherent and in line with the PR scope.

🤖 Prompt for AI Agents
In src/platform/remote/comfyui/jobs/fetchers/fetchJobs.ts around lines 24-160,
address the two reviewer suggestions: (1) Replace the hardcoded
QUEUE_PRIORITY_BASE with a configurable or derived value — e.g., read from
config or compute from a safe upper bound (Number.MAX_SAFE_INTEGER minus a
margin) and use that variable where QUEUE_PRIORITY_BASE is currently referenced;
(2) Make fetchJobsRaw distinguish between “empty result” and “fetch/parse error”
by returning an additional error flag or an Error object (or by throwing) so
callers can opt into treating failures differently from empty lists; update
callers (fetchHistory/fetchQueue) to handle the new return shape or catch the
thrown error accordingly.

Comment on lines +1 to +260
import { describe, expect, it, vi } from 'vitest'

import {
extractWorkflow,
fetchHistory,
fetchJobDetail,
fetchQueue
} from '@/platform/remote/comfyui/jobs'

// Helper to create a mock job
function createMockJob(
id: string,
status: 'pending' | 'in_progress' | 'completed' = 'completed',
overrides: Record<string, unknown> = {}
) {
return {
id,
status,
create_time: Date.now(),
execution_start_time: null,
execution_end_time: null,
preview_output: null,
outputs_count: 0,
...overrides
}
}

// Helper to create mock API response
function createMockResponse(
jobs: ReturnType<typeof createMockJob>[],
total: number = jobs.length
) {
return {
jobs,
pagination: {
offset: 0,
limit: 200,
total,
has_more: false
}
}
}

describe('fetchJobs', () => {
describe('fetchHistory', () => {
it('fetches completed jobs', async () => {
const mockFetch = vi.fn().mockResolvedValue({
ok: true,
json: () =>
Promise.resolve(
createMockResponse([
createMockJob('job1', 'completed'),
createMockJob('job2', 'completed')
])
)
})

const result = await fetchHistory(mockFetch)

expect(mockFetch).toHaveBeenCalledWith(
'/jobs?status=completed&limit=200&offset=0'
)
expect(result).toHaveLength(2)
expect(result[0].id).toBe('job1')
expect(result[1].id).toBe('job2')
})

it('assigns synthetic priorities', async () => {
const mockFetch = vi.fn().mockResolvedValue({
ok: true,
json: () =>
Promise.resolve(
createMockResponse(
[
createMockJob('job1', 'completed'),
createMockJob('job2', 'completed'),
createMockJob('job3', 'completed')
],
3
)
)
})

const result = await fetchHistory(mockFetch)

// Priority should be assigned from total down
expect(result[0].priority).toBe(3) // total - 0 - 0
expect(result[1].priority).toBe(2) // total - 0 - 1
expect(result[2].priority).toBe(1) // total - 0 - 2
})

it('preserves server-provided priority', async () => {
const mockFetch = vi.fn().mockResolvedValue({
ok: true,
json: () =>
Promise.resolve(
createMockResponse([
createMockJob('job1', 'completed', { priority: 999 })
])
)
})

const result = await fetchHistory(mockFetch)

expect(result[0].priority).toBe(999)
})

it('returns empty array on error', async () => {
const mockFetch = vi.fn().mockRejectedValue(new Error('Network error'))

const result = await fetchHistory(mockFetch)

expect(result).toEqual([])
})

it('returns empty array on non-ok response', async () => {
const mockFetch = vi.fn().mockResolvedValue({
ok: false,
status: 500
})

const result = await fetchHistory(mockFetch)

expect(result).toEqual([])
})
})

describe('fetchQueue', () => {
it('fetches running and pending jobs', async () => {
const mockFetch = vi.fn().mockResolvedValue({
ok: true,
json: () =>
Promise.resolve(
createMockResponse([
createMockJob('running1', 'in_progress'),
createMockJob('pending1', 'pending'),
createMockJob('pending2', 'pending')
])
)
})

const result = await fetchQueue(mockFetch)

expect(mockFetch).toHaveBeenCalledWith(
'/jobs?status=in_progress,pending&limit=200&offset=0'
)
expect(result.Running).toHaveLength(1)
expect(result.Pending).toHaveLength(2)
expect(result.Running[0].id).toBe('running1')
expect(result.Pending[0].id).toBe('pending1')
})

it('assigns queue priorities above history', async () => {
const mockFetch = vi.fn().mockResolvedValue({
ok: true,
json: () =>
Promise.resolve(
createMockResponse([
createMockJob('running1', 'in_progress'),
createMockJob('pending1', 'pending')
])
)
})

const result = await fetchQueue(mockFetch)

// Queue priorities should be above 1_000_000 (QUEUE_PRIORITY_BASE)
expect(result.Running[0].priority).toBeGreaterThan(1_000_000)
expect(result.Pending[0].priority).toBeGreaterThan(1_000_000)
// Pending should have higher priority than running
expect(result.Pending[0].priority).toBeGreaterThan(
result.Running[0].priority
)
})

it('returns empty arrays on error', async () => {
const mockFetch = vi.fn().mockRejectedValue(new Error('Network error'))

const result = await fetchQueue(mockFetch)

expect(result).toEqual({ Running: [], Pending: [] })
})
})

describe('fetchJobDetail', () => {
it('fetches job detail by id', async () => {
const jobDetail = {
...createMockJob('job1', 'completed'),
workflow: { extra_data: { extra_pnginfo: { workflow: {} } } },
outputs: {
'1': {
images: [{ filename: 'test.png', subfolder: '', type: 'output' }]
}
}
}
const mockFetch = vi.fn().mockResolvedValue({
ok: true,
json: () => Promise.resolve(jobDetail)
})

const result = await fetchJobDetail(mockFetch, 'job1')

expect(mockFetch).toHaveBeenCalledWith('/jobs/job1')
expect(result?.id).toBe('job1')
expect(result?.outputs).toBeDefined()
})

it('returns undefined for non-ok response', async () => {
const mockFetch = vi.fn().mockResolvedValue({
ok: false,
status: 404
})

const result = await fetchJobDetail(mockFetch, 'nonexistent')

expect(result).toBeUndefined()
})

it('returns undefined on error', async () => {
const mockFetch = vi.fn().mockRejectedValue(new Error('Network error'))

const result = await fetchJobDetail(mockFetch, 'job1')

expect(result).toBeUndefined()
})
})

describe('extractWorkflow', () => {
it('extracts workflow from nested structure', () => {
const jobDetail = {
...createMockJob('job1', 'completed'),
workflow: {
extra_data: {
extra_pnginfo: {
workflow: { nodes: [], links: [] }
}
}
}
}

const workflow = extractWorkflow(jobDetail)

expect(workflow).toEqual({ nodes: [], links: [] })
})

it('returns undefined if workflow not present', () => {
const jobDetail = createMockJob('job1', 'completed')

const workflow = extractWorkflow(jobDetail)

expect(workflow).toBeUndefined()
})

it('returns undefined for undefined input', () => {
const workflow = extractWorkflow(undefined)

expect(workflow).toBeUndefined()
})
})
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Strong coverage for fetchers; consider a couple of small edge‑case tests

These tests do a good job exercising URL construction, synthetic priority behavior, error handling, and extractWorkflow. Two non‑blocking enhancements you might consider:

  • Add a fetchHistory test with a non‑zero offset to lock in the total - offset priority base across pages.
  • Mirror the history “non‑ok response” case for fetchQueue (currently only network rejection is covered) and, optionally, a queue case where the server provides its own priority to document that we intentionally preserve it.

Based on learnings, this aligns well with the Vitest and mocking guidance for tests-ui/ but these extra cases would future‑proof the behavior a bit more.

🤖 Prompt for AI Agents
tests-ui/tests/platform/remote/comfyui/jobs/fetchJobs.test.ts lines 1-260: add
two small tests—one for fetchHistory with a non‑zero offset to verify synthetic
priority calculation uses total - offset correctly across pages, and one for
fetchQueue to handle a non‑ok server response (e.g., ok: false, status: 500)
returning { Running: [], Pending: [] }; optionally also add a queue test where
the server returns a job with an explicit priority to assert that priority is
preserved. Implement these by mocking fetch to return the appropriate response
shape, calling the respective function, and asserting on priorities and
empty-result behavior as described.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants